package com.github.tangyi.exam.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.util.StringUtils;
import com.github.tangyi.api.exam.model.Course;
import com.github.tangyi.api.user.attach.AttachmentManager;
import com.github.tangyi.api.user.attach.MultipartFileUploadContext;
import com.github.tangyi.api.user.enums.AttachTypeEnum;
import com.github.tangyi.api.user.model.Attachment;
import com.github.tangyi.api.user.model.Tenant;
import com.github.tangyi.api.user.model.User;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.BlockElement;
import com.itextpdf.layout.element.IElement;
import com.itextpdf.layout.font.FontProvider;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.UUID;

public class HtmlToPdfUtil {

    public static final String tempHtml = "<!DOCTYPE html>\n" +
            "<html lang=\"en\">\n" +
            "\n" +
            "<head>\n" +
            "  <meta charset=\"UTF-8\">\n" +
            "  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
            "  <title>Document</title>\n" +
            "  <style type=\"text/css\">\n" +
            "    body {\n" +
            "      margin: 0 auto;\n" +
            "    }\n" +
            "\n" +
            "    .cert-main {font-size:14px; color:#333333; line-height:1.1; margin-left:0px; margin-top:0px; background-image:url('https://oss.guilan.cn/04ade258ef664810b36556c7f24308a1.png'); background-size:cover; background-repeat:no-repeat; overflow:hidden; position:relative; width:1300px; height:900px;}\n" +
            "\n" +
            "    .title {font-size:74px; color:#2d70a8; line-height:95px; letter-spacing:15px; position:absolute; margin-left:330px; margin-top:90px; text-align:center; width:640px; font-family:Source Han Serif CN;}\n" +
            "\n" +
            "    .cert-info {font-size:38px; color:#333333; line-height:80px; position:absolute; margin-left:100px; margin-top:391px; font-family:Source Han Serif CN;}\n" +
            "    \n" +
            "    .student-info{\n" +
            "      /* color: #333333;\n" +
            "      font-size: undefinedpx;\n" +
            "      display: flex;\n" +
            "      justify-content: flex-start;\n" +
            "      height: undefinedpx;\n" +
            "      margin-top: 20px; */\n" +
            "      display: flex;\n" +
            "      justify-content: flex-start;\n" +
            "    }\n" +
            "\n" +
            "    .student-info-title {\n" +
            "      letter-spacing: 76px;\n" +
            "      margin-right: -76px;\n" +
            "    }\n" +
            "\n" +
            "    .cert-content {}\n" +
            "\n" +
            "    .cert-number {font-size:34px; color:#666666; line-height:1.1; position:absolute; margin-left:330px; margin-top:300px; text-align:center; width:640px; font-family:Source Han Serif CN;}\n" +
            "\n" +
            "\n" +
            "\n" +
            "    .code-content {\n" +
            "      background-color: #EBEBEB;\n" +
            "      box-sizing: border-box;\n" +
            "      padding: 10px;\n" +
            "      position: absolute;\n" +
            "      /* 修改 二维码*/\n" +
            "      margin-top: 670px;\n" +
            "      margin-left: 100px;\n" +
            "      text-align: center;\n" +
            "      width: 120;\n" +
            "      height: 160px;\n" +
            "    }\n" +
            "\n" +
            "    .code-padding {\n" +
            "      width: 100px;\n" +
            "      height: 100px;\n" +
            "      background-color: white;\n" +
            "      display: flex;\n" +
            "      justify-content: center;\n" +
            "      align-items: center;\n" +
            "    }\n" +
            "\n" +
            "    .code {\n" +
            "      width: 90px;\n" +
            "      height: 90px;\n" +
            "      background-image: url('$qrCode$');\n" +
            "      background-size: cover;\n" +
            "      background-repeat: no-repeat;\n" +
            "    }\n" +
            "\n" +
            "    .cert-query {\n" +
            "      text-align: center;\n" +
            "      font-size: 24px;\n" +
            "      margin-top: 15px;\n" +
            "    }\n" +
            "\n" +
            "    .issue-date {font-size:32px; color:#333333; line-height:1.1; position:absolute; margin-left:243px; margin-top:723px; font-family:Source Han Serif CN;}\n" +
            "\n" +
            "    .issue-org {font-size:32px; color:#333333; line-height:1.1; position:absolute; margin-left:243px; margin-top:784px; font-family:Source Han Serif CN;}\n" +
            "\n" +
            "    .seal {}\n" +
            "\n" +
            "    .score-level {font-size:48px; color:#e04547; line-height:1.1; position:absolute; margin-left:1013px; margin-top:460px; text-align:center; width:100px; font-family:Source Han Serif CN;}\n" +
            "  </style>\n" +
            "</head>\n" +
            "\n" +
            "<body>\n" +
            "  <div class=\"cert-main\">\n" +
            "    <div class=\"title\">结课证书</div>\n" +
            "    <div class=\"cert-number\">$certCode$</div>\n" +
            "    <!-- 学生信息 -->\n" +
            "    \n" +
            "        <div class=\"cert-info\">\n" +
            "          <div class=\"student-info\">\n" +
            "        <div class=\"student-info-title\">\n" +
            "          姓名\n" +
            "        </div>\n" +
            "        <div>\n" +
            "           ：$studentName$\n" +
            "        </div>\n" +
            "      </div><div class=\"student-info\">\n" +
            "        <div class=\"student-info-title\">\n" +
            "          学号\n" +
            "        </div>\n" +
            "        <div>\n" +
            "           ：$studentNumber$\n" +
            "        </div>\n" +
            "      </div><div class=\"student-info\">\n" +
            "        <div class=\"student-info-title\">\n" +
            "          学校\n" +
            "        </div>\n" +
            "        <div>\n" +
            "           ：$orgName$\n" +
            "        </div>\n" +
            "      </div>\n" +
            "        </div>\n" +
            "    <!-- 证书内容 -->\n" +
            "    \n" +
            "    <!-- 颁发日期 -->\n" +
            "    <div class=\"issue-date\">\n" +
            "      <span>\n" +
            "        颁发日期：\n" +
            "      </span>\n" +
            "      <span>\n" +
            "        $publishTime$\n" +
            "      </span>\n" +
            "    </div>\n" +
            "    <!-- 发证机构 -->\n" +
            "    <div class=\"issue-org\">\n" +
            "      <span>\n" +
            "        发证机构：\n" +
            "      </span>\n" +
            "      <span>\n" +
            "        $grantOrg$\n" +
            "      </span>\n" +
            "    </div>\n" +
            "    <!-- 印章 -->\n" +
            "    \n" +
            "    <!-- 成绩等级 -->\n" +
            "         <div class=\"score-level\">\n" +
            "      $scoreLevel$\n" +
            "     </div>\n" +
            "  </div>\n" +
            "</body>\n" +
            "\n" +
            "</html>";

    public static Attachment createCert(String fontPath, AttachmentManager attachmentManager, Course course, User user, Tenant tenant) throws IOException {
        String html = tempHtml;
        html = html.replace("$courseName$", course.getCourseName());
        if (StringUtils.isNotBlank(user.getName())) {
            html = html.replace("$studentName$", user.getName());
        }
        html = html.replace("$studentNumber$", user.getId()+"");
        html = html.replace("$orgName$", tenant.getTenantName());
        html = html.replace("$publishTime$", DateUtil.format(new Date(), "yyyyMMdd"));
        html = html.replace("$grantOrg$", tenant.getTenantName());

        // 8. 证书上链和证书编号
        String certCode = "No." + UUID.randomUUID().toString().replace("-", "");
        html = html.replace("$certCode$", certCode);
        html = html.replace("$scoreLevel$", "合格");
        String pdfUrl = "temp/"+ IdUtil.fastUUID().replace("-","")+".pdf";
        covertToPdf(html, pdfUrl, fontPath);
        return convertToImage(pdfUrl, attachmentManager);
    }

    /**
     * html转pdf
     *
     * @param htmlContent html内容
     * @param urlPath pdf保存路径
     * @param fontPath 字体路径
     * @throws IOException 异常
     */
    private static void covertToPdf(String htmlContent, String urlPath, String fontPath) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream(urlPath);
        fileOutputStream.write(convert(htmlContent, fontPath));
        fileOutputStream.close();
    }

    /**
     * pdf写入html内容
     *
     * @param html html内容
     * @return byte[] 字节数组
     * @throws IOException
     */
    public static byte[] convert(String html, String fontPath) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        PdfWriter writer = new PdfWriter(outputStream);
        PdfDocument pdfDocument = new PdfDocument(writer);
        try {
            ConverterProperties props = new ConverterProperties();
            FontProvider fp = new FontProvider();
            fp.addStandardPdfFonts();
            fp.addFont(fontPath);
            props.setFontProvider(fp);
            List<IElement> iElements = HtmlConverter.convertToElements(html, props);
            Document document = new Document(pdfDocument, PageSize.B4.rotate(), true);
            document.setMargins(10f, 0f, 2f, 12f);
            for (IElement iElement : iElements) {
                BlockElement blockElement = (BlockElement) iElement;
                blockElement.setMargins(1, 0, 1, 0);
                document.add(blockElement);
            }
            document.close();
            return outputStream.toByteArray();
        } catch (Exception e) {
            throw e;
        } finally {
            outputStream.close();
        }

    }


    /**
     * 转换成功图片
     *
     * @param pdfUrl    文件地址
     * @throws IOException 抛出异常
     */
    private static Attachment convertToImage(String pdfUrl, AttachmentManager attachmentManager) throws IOException {

        File srcPdfFile = new File(pdfUrl);
        PDDocument document = Loader.loadPDF(srcPdfFile);
        PDFRenderer pdfRenderer = new PDFRenderer(document);
        // 默认切割第一页
        BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(0, 300, ImageType.RGB);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "jpg", outputStream);
        byte[] bytes = outputStream.toByteArray();

        String tempDir = "temp" + File.separator + UUID.randomUUID() + ".jpg";

        // 将字节数组写入文件
        File file = new File(tempDir);
        MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", bytes);
        // 上传至oss
        Attachment attachment = attachmentManager.upload(MultipartFileUploadContext.of(AttachTypeEnum.DEFAULT, multipartFile));

        outputStream.close();
        document.close();
        // 删除对应的文件
        if (srcPdfFile.exists()) {
            srcPdfFile.delete();
        }
        if (file.exists()) {
            file.delete();
        }
        return attachment;
    }

    public static void main(String[] args) throws IOException {
        try {
            System.out.println(tempHtml);

            String pdfUrl = "temp//"+ IdUtil.fastUUID().replace("-","")+".pdf";
            covertToPdf(tempHtml, pdfUrl, "C:\\develop\\sg-exam-master\\sg-exam-master\\sg-user-service\\src\\main\\resources\\font\\simhei.ttf");

            File srcPdfFile = new File(pdfUrl);
            PDDocument document = Loader.loadPDF(srcPdfFile);
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            // 默认切割第一页
            BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(0, 300, ImageType.RGB);

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "jpg", outputStream);
            byte[] bytes = outputStream.toByteArray();

            String tempDir = "temp" + File.separator + UUID.randomUUID() + ".jpg";

            // 将字节数组写入文件
            File file = new File(tempDir);
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(bytes);

            // 上传至oss
//            Attachment attachment = attachmentManager.upload(MultipartFileUploadContext.of(AttachTypeEnum.DEFAULT, multipartFile));

            outputStream.close();
            document.close();
            fos.close();
            // 删除对应的文件
            if (srcPdfFile.exists()) {
                srcPdfFile.delete();
            }
//            if (file.exists()) {
//                file.delete();
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("PDF生成成功！");
    }
}
